package business;

import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

import persistence.db.DataSet;
import persistence.model.AbstractModel;
import persistence.model.Groupe;
import persistence.model.Seance;
import persistence.model.Semestre;
import persistence.model.UE;
import utility.Record;

public class SemestreBL {

	private Semestre sem = null;
	ArrayList<String> listeErreurs = null;
	
	public SemestreBL(){
		
	}
	
	public SemestreBL(int semestreId) {
		sem = (Semestre) Semestre.all().get(semestreId);
	}
	
		/**
	 * @return retourne si le format de la date est valide ou non
	 */
	public boolean invalideDate(String d){	
		String strDay = d.substring(0, 2);
		String strMonth = d.substring(3,5);
		String strYear =d.substring(6,10);
		GregorianCalendar gc=new GregorianCalendar(); 
		boolean invalide = false;
		if((gc.get(Calendar.YEAR)-Integer.parseInt(strYear)) > 2 || 
				   (gc.get(Calendar.YEAR)-Integer.parseInt(strYear)) < -2 ||
				   Integer.parseInt(strMonth)>12 || Integer.parseInt(strMonth)<=0 ||
				   Integer.parseInt(strDay)>31 || Integer.parseInt(strDay)<=0)
				{
					invalide = true;
					return invalide;
				}
		else if(d.length() != 10){
			invalide = true;
			return invalide;
		}
		else{						
			SimpleDateFormat s=new SimpleDateFormat("dd/MM/yyyy");
			Date date = null;
			try{
				date = (Date) s.parse(d);
			}catch(Exception e){
				//si n'a pas reussi a transformer le string vers date, format de la date invalide
				invalide = true;
				return invalide;
			}
			String s1 = s.format(date);
			// retransformer la date vers type String, si n'est pas pareil qu'avant, logique erreur
				invalide = !d.equals(s1);
				return invalide;
			} 	
	}

	/**
	 * @return retourne si la date debut est apres la date fin
	 */
	public boolean dateDepasse(String dateDebut, String dateFin){
		boolean dateDepasseErreur =false;
		DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        try {
            Date debut = (Date) df.parse(dateDebut);
            Date fin = (Date) df.parse(dateFin);
            if (debut.getTime() >= fin.getTime()) {
                dateDepasseErreur = false;
            } 
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return dateDepasseErreur;
	}
	
	/**
	 * @return retourne si la demande d'ajout ou de modification est valide ou non
	 */
	public boolean estValidePourModif(){
		boolean estValide = true;
		boolean existeDeja = false;
		
/*		for (AbstractModel semestre : Semestre.all())
		{
			Semestre sCourant = (Semestre)semestre;
			if(sCourant.getNomSemestre().equals(sem.getNomSemestre())){
				existeDeja = true;
				estValide = false;
			}
		}
		if(existeDeja){
			listeErreurs.add("Ce semestre existe déjà.");				
		}
		if(invalideDate(sem.getDebutSemestre()) || invalideDate(sem.getFinSemestre())){
			estValide = false;
			listeErreurs.add("La date n'est pas valide.");
		}
		if(dateDepasse(sem.getDebutSemestre(), sem.getFinSemestre())){
			estValide = false;
			listeErreurs.add("La date début ne peut pas dépassée la date fin.");
		}
*/			System.out.println(listeErreurs);
			return estValide;
	}
	

	/**
	 * @return retourne si la demande de suppression est valide ou non
	 */
	public boolean estValidePourSuppr(){
		boolean estValide = true;
		
		// S'il existe des UEs associees au semestre a supprime, n'est pas valide
		ArrayList<Record> listeUE = getListeUE();
		ArrayList<Record> listeGroupes = getListeGroupe();
		
		if (!listeUE.isEmpty()) {
			listeErreurs.add("Semestres existants à ce semestre.");
			estValide = false;
		}
		else if (!listeGroupes.isEmpty()){
			listeErreurs.add("Groupes existants à ce semestre.");
			estValide = false;
		}
		else {
			estValide = true;
		}
		return estValide;
	}
	
	/**
	 * @param id : identifiant du semestre
	 * @param nom : nom du semestre
	 * @param debut : date de début du semestre
	 * @param fin : date de fin du semestre
	 */
	public ArrayList<String> ajouterSemestre(int id, String nom, String debut, String fin, int nbGp, int gpPromo, int idAE, DataSet dsUE, DataSet dsGroupe) {
		sem = new Semestre(id, nom, debut, fin, nbGp, gpPromo, idAE, dsUE, dsGroupe);
		ArrayList<String> listeErreurs = new ArrayList<String>();
		if (this.estValidePourModif()) {
			sem.save();
//			Groupe groupe = new Groupe(1, "Promotion", 0, sem.getId(), null);
//			groupe.save();
		}
		return listeErreurs;
	}
	
	/**
	 * @param id : identifiant du semestre
	 * @param nom : nom du semestre
	 * @param debut : date de début du semestre
	 * @param fin : date de fin du semestre
	 */
	public ArrayList<String> modifierSemestre(int id, String nom, String debut, String fin, int nbGp, int gpPromo, int idAE, DataSet dsUE, DataSet dsGroupe) {
		sem = new Semestre(id, nom, debut, fin, nbGp, gpPromo, idAE, dsUE, dsGroupe);
		Groupe groupe = new Groupe(1, "Promotion", 0, sem.getId(), null);
		ArrayList<String> listeErreurs = new ArrayList<String>();
		if (this.estValidePourModif()) {
			sem.save();
			groupe.save();
		}
		return listeErreurs;
	}
	
	/**
	 * @param id : identifiant du semestre
	 */
	public ArrayList<String> supprimerSemestre() {		
		ArrayList<String> listeErreurs = new ArrayList<String>();
		if (this.estValidePourSuppr()) {
			sem.delete();
		}
		return listeErreurs;
	}
	
	/* Ensemble des getters et setters -> delegation vers la persistance */
	
	public int getIdSemestre() {
		return sem.getId();
	}

	public void setIdSemestre(int idSemestre) {
		sem.setId(idSemestre);
	}

	public String getNomSemestre() {
		return sem.getNomSemestre();
	}
	
	public void setNomSemestre(String nomSemestre) {
		sem.setNomSemestre(nomSemestre);
	}

	public String getDebutSemestre() {
		return sem.getDebutSemestre();
	}

	public void setDebutSemestre(String debutSemestre) {
		sem.setDebutSemestre(debutSemestre);
	}

	public String getFinSemestre() {
		return sem.getFinSemestre();
	}

	public void setFinSemestre(String finSemestre) {
		sem.setFinSemestre(finSemestre);
	}
	
	public int getNbGp() {
		return sem.getNbGroupe();
	}

	public void setNbGp(int nb) {
		sem.setNbGroupe(nb);
	}
	
	public int getGpPromo() {
		return sem.getGroupePromo();
	}

	public void setGpPromo(int gp) {
		sem.setGroupePromo(gp);
	}
 
	public int getIdAE() {
		return sem.getIdAnneeEtude();
	}

	public void setIdAE(int gp) {
		sem.setIdAnneeEtude(gp);
	}

	public DataSet getUe() {
		return sem.getUe();
	}
	public void setUe(DataSet ue) {
		sem.setUe(ue);
	}

	public DataSet getGroupe() {
		return sem.getGroupe();
	}	
	public void setGroupe(DataSet groupe) {
		sem.setGroupe(groupe);
	}

	public ArrayList<Record> getListeUE() {
		ArrayList<Record> listeUE = new ArrayList<Record>();

		for (AbstractModel ue : UE.all().filter(
				" FK_UE_SEMESTRE = " + sem.getId())) {
			
			UE ueCourant = (UE)ue;

			int idUE = ueCourant.getId();
			String nomUE = ueCourant.getNomUE();
			listeUE.add(new Record(idUE, nomUE));
		}

		return listeUE;
	}

	public ArrayList<Record> getListeGroupe() {
		ArrayList<Record> listeGrp = new ArrayList<Record>();

		for (AbstractModel grp : Groupe.all().filter(
				" FK_GROUPE_SEMESTRE = " + sem.getId())) {
			
			Groupe grpCourant = (Groupe)grp;

			int idGrp = grpCourant.getId();
			String nomGrp = grpCourant.getNomGroupe();
			listeGrp.add(new Record(idGrp, nomGrp));
		}

		return listeGrp;
	}

	/**
	 * Accés à toutes les séances de la periode pour le semestre courant
	 * @param periode souhaitée
	 * @return ArrayListe de seance correspondant
	 */

	public ArrayList<Seance> getListeSeances(int idPeriode) {
		//TODO
		return null;
	}

}
